package easyui

import (
	"bytes"
	"database/sql"
	"encoding/json"
	"fmt"
	"github.com/dchest/captcha"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"github.com/liuhangkaixcode/lhktools"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/disk"
	"github.com/shirou/gopsutil/v3/host"
	"github.com/shirou/gopsutil/v3/mem"
	"github.com/shirou/gopsutil/v3/net"
	"io/ioutil"
	"lhkdemo/logdemo"
	"net/http"
	"path"
	"strconv"
	"strings"
	"time"
)

func InitV1Router(enginer *gin.Engine) {
	enginer.Use(Cors(), func(c *gin.Context) {

		inserttime:=time.Now().Unix()
		method:=c.Request.Method
		c.Request.ParseForm()
		params:=fmt.Sprintf("%v",c.Request.Form)
		urlstr:=c.Request.URL.String()
		if urlstr =="/v1/listlog"{
			c.Next()
			return
		}

		loginip := strings.Split(c.Request.RemoteAddr, ":")[0]
		user:="admin"
		sqlstr:=fmt.Sprintf("insert into logs (method,path,param,user,handletime,ipaddress)values('%s','%s','%s','%s','%d','%s')",method,urlstr,params,user,inserttime,loginip)
		 mysqlmanger.Insert(sqlstr)
		c.Next()
	})
	en := enginer.Group("v1")
	{ //v1 start
		en.GET("/a", func(c *gin.Context) {
			apiname := []string{"/order", "/list", "/paymoney", "/getmessage"}
			time.Sleep(time.Nanosecond * 2)
			timennn := getTime()
			api := timennn % 4
			t1 := make(map[string]interface{})
			if timennn%4 == 1 {
				time.Sleep(time.Nanosecond * 2)
				api = getTime() % 4
				t1["apiname"] = apiname[api]
				t1["content"] = "哎呀-失败了"
				marshal, _ := json.Marshal(t1)
				logdemo.Logger.Error(string(marshal))

			} else {
				t1["apiname"] = apiname[api]
				t1["content"] = "恭喜-成功了"
				marshal, _ := json.Marshal(t1)
				logdemo.Logger.Info(string(marshal))
			}

			c.JSON(200, "success")
		})

		en.POST("/b", func(c *gin.Context) {
			loginip := strings.Split(c.Request.RemoteAddr, ":")[0]
			fmt.Println("===>>>", loginip)

			c.Header("aaaa_bbb_liuhangkai", fmt.Sprintf("%d", time.Now().Unix()))
			m := map[string]interface{}{"name": "age", "age": 19, "height": 192.2, "sex": false}
			marshal, _ := json.Marshal(m)
			c.Header("My-Content", string(marshal))
			c.JSON(414, "上游服务器异常")
		})
		//查询
		en.POST("/c", func(c *gin.Context) {
			token := c.Query("token")
			if len(token) == 0 {
				return
			}

			querStr:=fmt.Sprintf("select * from menu where find_in_set(id,(select role.menu_ids from role,user where user.role_id=role.id and user.token='%s'))",token)
			var tokenresult []Menu //TOKEN角色所对应的菜单
			err := mysqlmanger.Select(querStr, &tokenresult)
			if err != nil || len(tokenresult)==0{
				c.JSON(400,gin.H{"code":201,"msg":"token失效重新登录"})
				return
			}

			sqlstr := "select * from menu where isdir='1'"
			var dirallmenu []Menu
			err = mysqlmanger.Select(sqlstr, &dirallmenu)
			if err != nil {
				fmt.Print("报错-dirallmenu>", err)
				return
			}

			sqlstr = "select * from menu"
			var allMenu []Menu
			err = mysqlmanger.Select(sqlstr, &allMenu)
			if err != nil {
				fmt.Print("all=报错-allMenu->", err)
				return
			}
			//只有子菜单  通过子菜单找菜单目录
			finalR := getTokenMeun(dirallmenu, tokenresult, allMenu)
			r1 := GetMenu(SelectSort(finalR), 0)
			c.JSON(200, r1)

		})
		//列表menu菜单
		en.POST("/listmenu", func(c *gin.Context) {
			var result []Menu
			sqlstr := "select * from menu"

			err := mysqlmanger.Select(sqlstr, &result)
			if err != nil {
				fmt.Print("报错->", err)
				return
			}
			r1 := GetMenu(SelectSort(result), 0)
			c.JSON(200, r1)
		})
		//菜单编辑
		en.POST("/d", func(c *gin.Context) {

			var result []Menu
			sqlstr := "select * from menu"

			err := mysqlmanger.Select(sqlstr, &result)
			if err != nil {
				fmt.Print("报错->", err)
				return
			}
			r1 := GetMenu(SelectSort(result), 0)
			c.JSON(200, []interface{}{map[string]interface{}{"id": 0, "text": "根", "children": r1, "pid": 19871987, "isdir": "1"}})

		})

		en.POST("/addmenu", func(c *gin.Context) {
			type AddMenu struct {
				IsDir    string `json:"isdir"`
				MenuName string `json:"menuname"`
				OrderNum string `json:"ordernum"`
				Path     string `json:"path"`
				Pid      string `json:"pid"`
				ID       string `json:"id"`
			}
			data, _ := ioutil.ReadAll(c.Request.Body)
			var tt AddMenu
			err := json.Unmarshal(data, &tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "解析前端报文报错" + err.Error()})
				return
			}

			//更新操作
			if len(tt.ID) > 0 {
				fmt.Println("菜单执行了更新操作")
				updatestr := fmt.Sprintf("update  menu set text='%s',path='%s',sortnum='%s' where id='%s'", tt.MenuName, tt.Path, tt.OrderNum, tt.ID)
				_, err := mysqlmanger.UpdateOrDelete(updatestr)
				if err != nil {
					c.JSON(200, gin.H{"code": "203", "msg": err.Error() + updatestr})
					return
				}
				c.JSON(200, gin.H{"code": "200", "msg": "update success"})

				return
			}

			_, err1 := strconv.Atoi(tt.Pid)
			_, err2 := strconv.Atoi(tt.OrderNum)
			if err1 != nil || err2 != nil {
				fmt.Println(err1, err2)
				c.JSON(200, gin.H{"code": "401", "msg": "pid,ordernum不为字符串"})
				return
			}
			if tt.IsDir == "0" {
				if len(tt.Path) == 0 {
					c.JSON(200, gin.H{"code": "401", "msg": "不是目录且path不能为空"})
					return
				}
			}

			if tt.IsDir == "1" {
				if len(tt.Path) != 0 {
					c.JSON(200, gin.H{"code": "401", "msg": "目录创建时，path不能有值"})
					return
				}
			}

			var path sql.NullString
			str := fmt.Sprintf("select path from menu where id='%s'", tt.Pid)
			err = mysqlmanger.Get(str, &path)

			if err != nil {
				if strings.Contains(err.Error(), "sql: no rows in result set") {
					fmt.Print("baocuo", err.Error(), "没有查询到数据或者数据为空")
				} else {
					c.JSON(200, gin.H{"code": "401", "msg": str + "查看父菜单的path报错" + err.Error() + str})
					return
				}
			}
			if len(path.String) > 0 {
				c.JSON(200, gin.H{"code": "401", "msg": "父菜单的path不为空，可能是父目录是子菜单"})
				fmt.Println("path--->", path)
				return
			}

			queryStr := fmt.Sprintf("select count(*) as total from menu where pid='%s' and text='%s' and isdir='%s'", tt.Pid, tt.MenuName, tt.IsDir)

			var total int
			err = mysqlmanger.Get(queryStr, &total)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "counterror"})
				return
			}
			fmt.Println("total==>", total)
			//添加逻辑
			if total == 0 {
				//没有数据
				queryStr := fmt.Sprintf("insert into menu(text,pid,path,isdir,sortnum) values('%s','%s','%s','%s','%s')", tt.MenuName, tt.Pid, tt.Path, tt.IsDir, tt.OrderNum)
				fmt.Println("")
				_, err = mysqlmanger.Insert(queryStr)
				if err != nil {
					c.JSON(200, gin.H{"code": "400", "msg": err.Error() + queryStr})
					return
				}
				c.JSON(200, gin.H{"code": "200", "msg": "success"})
			} else {
				c.JSON(200, gin.H{"code": "400", "msg": "已经添加了"})
			}

		})

		en.POST("/editmenu", func(c *gin.Context) {
			var t map[string]string
			data, _ := ioutil.ReadAll(c.Request.Body)
			json.Unmarshal(data, &t)
			fmt.Println("==>", string(data), t)
			sqlstr := fmt.Sprintf("update menu set text='%s',path='%s',isdir='%s',sortnum='%s' where id='%s'", t["menuname"], t["path"], t["isdir"], t["ordernum"], t["id"])
			_, err := mysqlmanger.UpdateOrDelete(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": "400", "msg": err.Error()})
			} else {
				c.JSON(200, gin.H{"code": "200", "msg": "success"})
			}
		})
		//删除
		en.POST("/deletemenu", func(c *gin.Context) {

			id := c.PostForm("id")
			pid := c.PostForm("pid")
			isdir := c.PostForm("isdir")

			if id == "1" || pid == "1" {
				c.JSON(200, gin.H{"code": "201", "msg": "系统目录不能删除"})
				return
			}
			if isdir == "1" {
				sqlstr := fmt.Sprintf("select count(*) as total from menu where pid='%s'", id)
				var total int
				err := mysqlmanger.Get(sqlstr, &total)
				if err != nil {
					if !strings.Contains(err.Error(), NOSQLROW) {
						c.JSON(200, gin.H{"code": 201, "msg": "total" + err.Error()})
						return
					}
				}
				if total > 0 {
					c.JSON(200, gin.H{"code": 201, "msg": "目录无法删除,有子菜单"})
					return
				}
				deletestr := fmt.Sprintf("delete from menu where id='%s'", id)
				_, err = mysqlmanger.UpdateOrDelete(deletestr)
				if err != nil {
					c.JSON(200, gin.H{"code": 200, "msg": "目录" + err.Error()})
					return
				}
				c.JSON(200, gin.H{"code": 200, "msg": "目录删除成功"})

				return
			}
			var tt []*struct {
				Menu_id string `db:"menu_ids"`
			}
			err := mysqlmanger.Select("select menu_ids from role", &tt)
			if err != nil {
				if !strings.Contains(err.Error(), NOSQLROW) {
					c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
					return
				}
			}
			var candel bool = false
			if len(tt) == 0 {
				//直接可以删除
				candel = true
			} else {
				//需要遍历逻辑
				var tempstr []string
				for _, v := range tt {
					tempstr = append(tempstr, strings.Split(v.Menu_id, ",")...)
				}

				for _, y := range tempstr {
					if id == y {
						c.JSON(200, gin.H{
							"code": "201",
							"msg":  "无法删除,该菜单有其他角色在使用",
						})
						return
					}
				}
				candel = true
			}
			if candel {
				deletestr := fmt.Sprintf("delete from menu where id='%s'", id)
				_, err := mysqlmanger.UpdateOrDelete(deletestr)
				if err != nil {
					c.JSON(200, gin.H{"code": 200, "msg": err.Error()})
					return
				}
				c.JSON(200, gin.H{"code": 200, "msg": "删除成功"})
			}

		})

		en.POST("/addrole", func(c *gin.Context) {
			data, _ := ioutil.ReadAll(c.Request.Body)
			fmt.Println("==>", string(data))
			var tt struct {
				Name     string `json:"name"`
				Menu_ids string `json:"menu_ids"`
			}
			err := json.Unmarshal(data, &tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": err.Error()})
				return
			}
			sqlstr := fmt.Sprintf("insert into role(name,menu_ids)values('%s','%s')", tt.Name, tt.Menu_ids)
			fmt.Println(sqlstr)
			_, err = mysqlmanger.Insert(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": err.Error()})
				return
			}
			c.JSON(200, gin.H{"code": "200", "msg": "success"})
		})

		en.POST("/listroles", func(c *gin.Context) {
			page := c.PostForm("page")
			rows := c.PostForm("rows")
			filterRules := c.PostForm("filterRules")
			fmt.Println("==>page", page, "rows", rows, "filterRules", filterRules)

			var tt []struct {
				ID       int    `db:"id" json:"id"`
				Name     string `db:"name" json:"name"`
				Menu_ids string `db:"menu_ids" json:"menu_ids"`
			}
			sqlstr := "select id,name,menu_ids from role"
			err := mysqlmanger.Select(sqlstr, &tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": err.Error()})
				return
			}
			if len(tt) == 0 {
			}
			c.JSON(200, gin.H{"total": len(tt), "rows": tt})
		})

		en.POST("/deleterole", func(c *gin.Context) {
			data, _ := ioutil.ReadAll(c.Request.Body)
			fmt.Println("==>", string(data))
			var tt struct {
				ID string `json:"ID"`
			}
			err := json.Unmarshal(data, &tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "XDF" + err.Error()})
				return
			}
			//判断角色是否被用户使用
			sqlstr := fmt.Sprintf("select count(*) as total from user,role where user.role_id=role.id and role.id='%s'", tt.ID)
			var total int
			err = mysqlmanger.Get(sqlstr, &total)
			if err != nil {
				if !strings.Contains(err.Error(), NOSQLROW) {
					c.JSON(200, gin.H{"code": 400, "msg": err.Error() + sqlstr})
					return
				}
			}
			if total > 0 {
				c.JSON(200, gin.H{"code": 400, "msg": "该角色已经被用户使用->" + sqlstr})
				return
			}
			fmt.Println("sqlsttr", sqlstr)
			sqlstr = fmt.Sprintf("delete from role where id='%s'", tt.ID)
			_, err = mysqlmanger.UpdateOrDelete(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "SHU" + err.Error()})
				return
			}
			fmt.Println("==deleteSuccess")
			c.JSON(200, gin.H{"code": "200", "msg": "success"})
		})

		en.POST("/getroles", func(c *gin.Context) {
			data, _ := ioutil.ReadAll(c.Request.Body)
			fmt.Println("==>", string(data))
			var tt struct {
				ID string `json:"ID"`
			}
			err := json.Unmarshal(data, &tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "XDF" + err.Error()})
				return
			}
			var yy struct {
				ID       int    `db:"id" json:"id"`
				Name     string `db:"name" json:"name"`
				Menu_ids string `db:"menu_ids" json:"menu_ids"`
			}
			sqlstr := fmt.Sprintf("select * from role where id='%s'", tt.ID)
			mysqlmanger.Get(sqlstr, &yy)
			c.JSON(200, gin.H{"code": "200", "datas": yy})
		})

		en.GET("/getmenulist", func(c *gin.Context) {
			menu_ids := c.Query("p")
			split := strings.Split(menu_ids, ",")
			fmt.Println("==>>", split)

			var result []Menu
			sqlstr := "select * from menu"

			err := mysqlmanger.Select(sqlstr, &result)
			if err != nil {
				fmt.Print("报错->", err)
				return
			}
			r1 := GetMenu(SelectSort(checkIsChecked(result, split)), 0)
			c.JSON(200, r1)
		})

		en.POST("/editrole", func(c *gin.Context) {
			data, _ := ioutil.ReadAll(c.Request.Body)
			fmt.Println("==>", string(data))
			var tt struct {
				ID       string `db:"id" json:"id"`
				Name     string `db:"name" json:"name"`
				Menu_ids string `db:"menu_ids" json:"menu_ids"`
			}
			err := json.Unmarshal(data, &tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "XDF" + err.Error()})
				return
			}

			sqlstr := fmt.Sprintf("update role set name='%s',menu_ids='%s' where id='%s'", tt.Name, tt.Menu_ids, tt.ID)
			fmt.Println("sqlstr", sqlstr)
			_, err = mysqlmanger.UpdateOrDelete(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "update" + err.Error()})
				return
			}
			c.JSON(200, gin.H{"code": "200", "msg": "success"})
		})

		en.POST("/listuser", func(c *gin.Context) {
			var result []struct {
				UserId    int    `db:"id" json:"userid"`
				UserName  string `db:"username" json:"username"`
				Pwd       string `db:"pwd" json:"pwd"`
				Status    string `db:"status" json:"status"`
				LastLogin int    `db:"lastlogin" json:"lastlogin"`
				RoleName  string `db:"name" json:"rolename"`
				RoleId    int    `db:"roleid" json:"roleid"`
			}
			sqlstr := "select user.id,user.pwd,user.username,user.status,user.lastlogin,role.name,role.id as roleid from user,role where user.role_id=role.id"


			if len(c.PostForm("username"))>0 {
				sqlstr=fmt.Sprintf("%s and user.username like'%%%s%%'",sqlstr,c.PostForm("username"))
			}

			if len(c.PostForm("role"))>0 {
				sqlstr=fmt.Sprintf("%s and role.name like'%%%s%%'",sqlstr,c.PostForm("role"))
			}


			err := mysqlmanger.Select(sqlstr, &result)
			if err != nil {
				fmt.Print("报错->", err)
				c.JSON(200, gin.H{"code": "401", "msg": "user" + err.Error()})
				return
			}
			c.JSON(200, gin.H{"total": len(result), "rows": result})
		})

		en.POST("/adduser", func(c *gin.Context) {
			var tt struct {
				UserId   int    `form:"userid,string" bindding:"omitempty,gt=1"` //min=5,max=77
				UserName string `form:"username" binding:"required"`
				Pwd      string `form:"pwd" binding:"required"`
				Pwd2     string `form:"pwd2" binding:"required,eqfield=Pwd"`
				Status   string `form:"status" binding:"required"`
				RoleId   string `form:"roleid" bindding:"omitempty"`
			}
			err := c.ShouldBind(&tt)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "XDF" + err.Error()})
				return
			}
			marshal, _ := json.Marshal(tt)
			fmt.Println(string(marshal))
			sqlstr := ""
			token := lhktools.Md5Str(time.Now().String())
			lastlogin := fmt.Sprintf("%d", int(time.Now().Unix()))
			if tt.UserId > 0 {
				sqlstr = fmt.Sprintf("update user set username='%s',pwd='%s',status='%s',role_id='%s',token='%s',lastlogin='%s' where id='%d'", tt.UserName, tt.Pwd, tt.Status, tt.RoleId, token, lastlogin, tt.UserId)
			} else {
				sqlstr = fmt.Sprintf("insert into user(username,pwd,status,role_id,token,lastlogin)values('%s','%s','%s','%s','%s','%s')", tt.UserName, tt.Pwd, tt.Status, tt.RoleId, token, lastlogin)
			}

			_, err = mysqlmanger.UpdateOrDelete(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "insertorupdate" + err.Error() + sqlstr})
				return
			}
			fmt.Println(sqlstr)
			c.JSON(200, gin.H{"code": "200", "msg": "success"})
		})

		en.POST("/deleteuser", func(c *gin.Context) {
			var tt struct {
				UserID int `form:"userid,string" binding:"required" gt=1`
			}
			err := c.ShouldBind(&tt)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": "zhuanhua" + err.Error()})
				return
			}
			sqlstr := fmt.Sprintf("delete from user where id='%d'", tt.UserID)
			_, err = mysqlmanger.UpdateOrDelete(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": "dele" + err.Error() + sqlstr})
				return
			}
			c.JSON(200, gin.H{"code": 200, "msg": "success"})

		})

		en.POST("/login", func(c *gin.Context) {
			code := c.PostForm("code")
			captchId := c.PostForm("captchId")
			loginname := c.PostForm("loginname")
			password := c.PostForm("password")
			fmt.Println("===>login", code, captchId, loginname, password)
			if captcha.VerifyString(captchId, code) {
				fmt.Println("code验证成功")

			} else {
				c.JSON(http.StatusOK, gin.H{"code": "201", "msg": "验证码错误"})
				return
			}

			queryStr := fmt.Sprintf("select username,lastlogin,status  from user where username='%s' and pwd='%s'", loginname, password)
			var temp struct {
				UserName  string `db:"username"`
				LastLogin int    `db:"lastlogin"`
				Status string `db:"status"`
			}
			err := mysqlmanger.Get(queryStr, &temp)
			if err != nil {
				c.JSON(200, gin.H{"code": 201, "msg": err.Error() + "用户名和密码错误"})
				return
			}
			if len(temp.UserName) == 0 {
				c.JSON(200, gin.H{"code": 201, "msg": "用户名和密码错误"})
				return
			}

			if temp.Status == "0" {
				c.JSON(200, gin.H{"code": 201, "msg": "该账号已经被禁用"})
				return
			}

			token := lhktools.Md5Str(time.Now().String())
			lastlogin := fmt.Sprintf("%d", int(time.Now().Unix()))

			updateStr := fmt.Sprintf("update user set token='%s',lastlogin='%s' where username='%s'", token, lastlogin, loginname)
			_, err = mysqlmanger.UpdateOrDelete(updateStr)
			if err != nil {
				c.JSON(200, gin.H{"code": "401", "msg": "genxin" + err.Error()})
				return
			}
			fmt.Println("==>success=login")
			c.JSON(200, gin.H{"code": "200", "token": token, "lastlogin": temp.LastLogin, "loginname": loginname})

			return

		})

		en.POST("/liststu", func(c *gin.Context) {
			c.Request.ParseForm()
			fmt.Println("==>res",c.Request.Form)

			var temp struct{
				Page int `form:"page"`
				Rows int `form:"rows"`
				FilterRules string `form:"filterRules"`
			}
			c.ShouldBind(&temp)
			page:=temp.Page
			rows:=temp.Rows
			filterRulesstr := temp.FilterRules
			querywhereStr := ""
			//模糊查询 {"field":"height","op":"contains","value":"1"}
			if len(filterRulesstr) > 0 {
				var tt []map[string]string
				json.Unmarshal([]byte(filterRulesstr), &tt)
				for _, v := range tt {
					if len(v["value"]) == 0 {
						continue
					}
					//过滤hobby
					if(v["field"]=="hobby"){
						vstr:=v["value"]
						r:=""
						if strings.Contains(vstr,"篮球") {
							r=fmt.Sprintf("%s,'%s'",r,"0")
						}
						if strings.Contains(vstr,"排球") {
							r=fmt.Sprintf("%s,'%s'",r,"1")
						}
						if strings.Contains(vstr,"乒乓球") {
							r=fmt.Sprintf("%s,'%s'",r,"2")
						}
						if len(r)>0{
							r=fmt.Sprintf("%s",r[1:])
							querywhereStr = fmt.Sprintf("%sand json_contains(%s,json_array(%s)) ", querywhereStr, v["field"], r)
						}
						continue

					}
					//默认值
					op:=v["op"]
					if op == "equal" {
					querywhereStr = fmt.Sprintf("%sand %s='%s' ", querywhereStr, v["field"], v["value"])
					continue
					}
					querywhereStr = fmt.Sprintf("%sand %s like '%%%s%%' ", querywhereStr, v["field"], v["value"])

				}

			}

			querystr := ""
			countquerystr := ""
			var total int
			if len(querywhereStr) > 3 {
				querystr = fmt.Sprintf("select * from stu where %s limit %d,%d", querywhereStr[3:], (page-1)*rows, rows)
				countquerystr = fmt.Sprintf("select count(*) as total from stu where %s ", querywhereStr[3:])
			} else {
				querystr = fmt.Sprintf("select * from stu limit %d,%d", (page-1)*rows, rows)
				countquerystr = "select count(*) from stu"
			}

			fmt.Println("==>query",querystr)
			fmt.Println("====countquerstr",countquerystr)

			var res []struct {
				ID     int     `db:"id" json:"id"`
				Name   string  `db:"name" json:"name"`
				Height float64 `db:"height" json:"height"`
				Age    int     `db:"age" json:"age"`
				Logo   string  `db:"logo" json:"logo"`
				Hobby  string  `db:"hobby" json:"hobby"`
				Beizhu string  `db:"beizhu" json:"beizhu"`
				Sex    int     `db:"sex" json:"sex"`
				Birth  string  `db:"birth" json:"birth"`
			}

			err := mysqlmanger.Select(querystr, &res)

			if err != nil {
				if strings.Contains(err.Error(), "sql: no rows in result set") {
					ttt := make([]interface{}, 2)
					c.JSON(200, gin.H{"rows": ttt, "total": total})
					fmt.Println("==now=>", err.Error())
					return
				} else {
					c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
					fmt.Println("==error=>", err.Error())
					return
				}
			}

			err = mysqlmanger.Get(countquerystr, &total)
			if err != nil {
				if strings.Contains(err.Error(), "sql: no rows in result set") {

					c.JSON(200, gin.H{"code": 201, "msg": "没有查询到数据或者数据为空" + err.Error()})
					return
				} else {
					c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
					return
				}
			}
			c.JSON(200, gin.H{"rows": res, "total": total})
		})

		en.POST("/listlog", func(c *gin.Context) {

			var temp struct{
				Page int `form:"page"`
				Rows int `form:"rows"`
				FilterRules string `form:"filterRules"`
				StartTime string `form:"starttime"`
				EndTime string `form:"endtime"`
			}
			c.ShouldBind(&temp)
			page:=temp.Page
			rows:=temp.Rows
			filterRulesstr := temp.FilterRules
			querywhereStr := ""
			//模糊查询 {"field":"height","op":"contains","value":"1"}
			if len(filterRulesstr) > 0 {
				var tt []map[string]string
				json.Unmarshal([]byte(filterRulesstr), &tt)
				for _, v := range tt {
					if len(v["value"]) == 0 {
						continue
					}

					//默认值
					op:=v["op"]
					if op == "equal" {
						querywhereStr = fmt.Sprintf("%sand %s='%s' ", querywhereStr, v["field"], v["value"])
						continue
					}
					querywhereStr = fmt.Sprintf("%sand %s like '%%%s%%' ", querywhereStr, v["field"], v["value"])

				}

			}

			if (len(temp.StartTime)>0 && len(temp.EndTime)>0){
				querywhereStr = fmt.Sprintf("%sand %s>'%s' and %s<'%s' ", querywhereStr, "handletime",temp.StartTime,"handletime",temp.EndTime)
			}

			querystr := ""
			countquerystr := ""
			var total int
			if len(querywhereStr) > 3 {
				querystr = fmt.Sprintf("select * from logs where %s order by handletime desc limit %d,%d ", querywhereStr[3:], (page-1)*rows, rows)
				countquerystr = fmt.Sprintf("select count(*) as total from logs where %s ", querywhereStr[3:])
			} else {
				querystr = fmt.Sprintf("select * from logs order by handletime desc limit %d,%d", (page-1)*rows, rows)
				countquerystr = "select count(*) from logs"
			}

			//fmt.Println("==>query",querystr)
			//fmt.Println("====countquerstr",countquerystr)

			var res []struct {
				ID     int     `db:"id" json:"id"`
				Method   string  `db:"method" json:"method"`
				Path string `db:"path" json:"path"`
				Param    string     `db:"param" json:"param"`
				User   string  `db:"user" json:"user"`
				Handletime  int  `db:"handletime" json:"handletime"`
				Ipaddress string  `db:"ipaddress" json:"ipaddress"`
			}

			err := mysqlmanger.Select(querystr, &res)

			if err != nil {
				if strings.Contains(err.Error(), "sql: no rows in result set") {
					ttt := make([]interface{}, 2)
					c.JSON(200, gin.H{"rows": ttt, "total": total})
					fmt.Println("==now=>", err.Error())
					return
				} else {
					c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
					fmt.Println("==error=>", err.Error())
					return
				}
			}

			err = mysqlmanger.Get(countquerystr, &total)
			if err != nil {
				if strings.Contains(err.Error(), "sql: no rows in result set") {

					c.JSON(200, gin.H{"code": 201, "msg": "没有查询到数据或者数据为空" + err.Error()})
					return
				} else {
					c.JSON(200, gin.H{"code": 201, "msg": err.Error()})
					return
				}
			}
			c.JSON(200, gin.H{"rows": res, "total": total})
		})


		en.POST("/addstu", func(c *gin.Context) {

			var tmp struct { //binding:"required"
				ID     int      `form:"id,string" binding:"omitempty,lt=6000,gt=1"` //omitempty要么不传，传的话就要// [1,6000]
				Name   string   `db:"name" form:"name"binding:"required"`
				Height float64  `db:"height" form:"height,string" binding:"required"`
				Age    int      `db:"age" form:"age,string" binding:"required"`
				Birth  string   `db:"birth" form:"birth" binding:"required"`
				Hobby  []string `db:"hobby" form:"hobby" binding:"required,gt=0"`
				Sex    int      `db:"sex" form:"sex,string" binding:"omitempty"`
				Beizhu string   `db:"beizhu" form:"beizhu" binding:"required"`
				Logo   string   `db:"logo" form:"logo" binding:"required"`
			}
			err := c.ShouldBind(&tmp)
			fmt.Println(err, "err", tmp)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": "zhuanhua" + err.Error()})
				return
			}

			hobbybyte, _ := json.Marshal(tmp.Hobby)

			if tmp.ID > 0 {
				sqlstr := fmt.Sprintf("update stu set name='%s',age='%d',height='%.2f',logo='%s',birth='%s',beizhu='%s',sex='%d',hobby='%s' where id='%d'", tmp.Name, tmp.Age, tmp.Height, tmp.Logo, tmp.Birth, tmp.Beizhu, tmp.Sex, string(hobbybyte), tmp.ID)
				_, err = mysqlmanger.UpdateOrDelete(sqlstr)
				if err != nil {
					fmt.Println(err, "--updataerr", sqlstr)
					c.JSON(200, gin.H{"code": 400, "msg": err.Error() + sqlstr})
					return
				}
				fmt.Println("====>updatsuccess")
				c.JSON(200, gin.H{"code": 200, "msg": "updateSuccess"})
				return

			}
			sqlstr := fmt.Sprintf("insert into stu(name,age,height,logo,birth,beizhu,sex,hobby) values('%s','%d','%.2f','%s','%s','%s','%d','%s')", tmp.Name, tmp.Age, tmp.Height, tmp.Logo, tmp.Birth, tmp.Beizhu, tmp.Sex, string(hobbybyte))
			_, err = mysqlmanger.Insert(sqlstr)
			if err != nil {
				fmt.Println(err, "--inserterr", sqlstr)
				c.JSON(200, gin.H{"code": 400, "msg": err.Error() + sqlstr})
				return
			}
			fmt.Println("====>success")
			c.JSON(200, gin.H{"code": 200, "msg": "insertsuccess"})
		})

		en.POST("/delstu", func(c *gin.Context) {
			id := c.PostForm("id")
			idvalue, err := strconv.Atoi(id)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": "change error" + err.Error()})
				return
			}
			sqlstr := fmt.Sprintf("delete from stu where id='%d'", idvalue)
			_, err = mysqlmanger.UpdateOrDelete(sqlstr)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": "delete error" + err.Error()})
				return
			}
			c.JSON(200, gin.H{"code": 200, "msg": "delete success"})
		})

		//1.获取验证码
		//http://localhost:8787/captcha
		en.GET("/captcha", func(c *gin.Context) {
			length := 2 //captcha.DefaultLen
			type CaptchaResponse struct {
				CaptchaId string `json:"captchaId"` //验证码Id
				ImageUrl  string `json:"imageUrl"`  //验证码图片url
			}
			captchaId := captcha.NewLen(length)
			var captcha CaptchaResponse
			captcha.CaptchaId = captchaId
			captcha.ImageUrl = "/captcha/" + captchaId + ".png"
			c.JSON(http.StatusOK, captcha)
		})

		//2.获取验证码图片
		//http://localhost:8787/captcha/gHEIwh7nWreTFb53MkVk.png
		en.GET("/captcha/:captchaId", func(c *gin.Context) {
			captchaId := c.Param("captchaId")
			fmt.Println("GetCaptchaPng : " + captchaId)
			ServeHTTP(c.Writer, c.Request)
		})

		//3.验证
		//http://localhost:8787/verify/dVCqYbq7r2olKZfEtTvo/647489
		en.GET("/verify/:captchaId/:value", func(c *gin.Context) {
			captchaId := c.Param("captchaId")
			value := c.Param("value")
			if captchaId == "" || value == "" {
				c.String(http.StatusBadRequest, "参数错误")
			}
			if captcha.VerifyString(captchaId, value) {
				c.JSON(http.StatusOK, "验证成功")
			} else {
				c.JSON(http.StatusOK, "验证失败")
			}
		})

		//图片上传
		en.POST("/upload", func(c *gin.Context) {
			form, _ := c.MultipartForm()
			fmt.Println("form", form, "form1", form.Value)

			if len(form.File) == 0 {
				c.JSON(200, "form.file error")
				return
			}
			var resultFileNames []map[string]string

			for i := 1; i <= len(form.File); i++ {
				fileflag := fmt.Sprintf("image%d", i)
				if len(form.File) == 1 {
					fileflag = "image"
				}
				file, _ := c.FormFile(fileflag)
				tempName := fmt.Sprintf("%d-%s", time.Now().UnixNano(), file.Filename)
				ssname := fmt.Sprintf("easyui/static/%s", tempName)
				err := c.SaveUploadedFile(file, ssname)
				if err != nil {
					c.JSON(200, gin.H{"code": 400, "msg": "MULsaveuploadfile" + err.Error()})
					return
				}
				ma := make(map[string]string)
				ma["url"] = "http://14.116.147.19:8787/static/" + tempName
				ma["alt"] = "搞笑"
				ma["href"] = "http://www.baidu.com"

				resultFileNames = append(resultFileNames, ma)
				if len(form.File) == 1 {
					break
				}

			}
			kkk := gin.H{"errno": 0, "data": resultFileNames}
			fmt.Println(kkk)
			c.JSON(200, kkk)
		})

		en.POST("/listboke", func(c *gin.Context) {
			var Bokes []struct {
				ID      int    `db:"id" json:"id"`
				Title   string `db:"title" json:"title"`
				Content string `db:"content" json:"content"`
			}
			err := mysqlmanger.Select("select * from boke", &Bokes)
			if err != nil {
				if strings.Contains(err.Error(), NOSQLROW) {
					fmt.Sprint("nodata=", err)
					c.JSON(200, gin.H{"total": 0, "rows": Bokes})
					return
				}
				fmt.Sprint("data err=", err)
				c.JSON(200, gin.H{"total": 0, "msg": err.Error()})
				return
			}

			c.JSON(200, gin.H{"total": len(Bokes), "rows": Bokes})

		})
		//添加或者更新博客内容
		en.POST("/addorupdateboke", func(c *gin.Context) {

			var temp struct {
				Content string `form:"content" binding:"required"`
				Title   string `form:"title" binding:"required"`
				ID      int    `form:"id,string" binding:"omitempty,lt=6000,gt=1"` //omitempty要么不传，传的话就要// [1,6000]
			}
			err := c.ShouldBind(&temp)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": err.Error() + "shouldBind"})
				return
			}

			//更新过程
			if temp.ID > 0 {
				var total int
				sqlqueryStr := fmt.Sprintf("select count(*) as total from boke where id='%d'", temp.ID)
				err = mysqlmanger.Get(sqlqueryStr, &total)
				if err != nil {
					c.JSON(200, gin.H{"code": 400, "msg": sqlqueryStr + err.Error()})
					return
				}
				temp.Content = strings.Replace(temp.Content, "'", "\\'", -1)
				updatestr := fmt.Sprintf("update boke set title='%s',content='%s' where id='%d'", temp.Title, temp.Content, temp.ID)
				_, err = mysqlmanger.UpdateOrDelete(updatestr)
				if err != nil {
					c.JSON(200, gin.H{"code": 400, "msg": updatestr + err.Error()})
					fmt.Println(temp.Content)
					return
				}
				c.JSON(200, gin.H{"code": 200, "msg": "更新成功"})
				return
			}
			temp.Content = strings.Replace(temp.Content, "'", "\\'", -1)
			sqlstr := fmt.Sprintf("insert into boke(title,content)values('%s','%s')", temp.Title, temp.Content)
			_, err = mysqlmanger.Insert(sqlstr)
			if err != nil {
				fmt.Println(err, "error", sqlstr)
				c.JSON(200, gin.H{"code": 400, "msg": "insert" + err.Error() + sqlstr})
				return
			}
			c.JSON(200, gin.H{"code": 200, "msg": "insert success"})

		})

		en.POST("/delboke", func(c *gin.Context) {
			var temp struct {
				ID int `form:"id,string" binding:"required" `
			}
			err := c.ShouldBind(&temp)
			if err != nil {
				c.JSON(200, gin.H{"code": 400, "msg": "delboke should" + err.Error()})
				return
			}

			delstr := fmt.Sprintf("delete from boke where id='%d'", temp.ID)
			_, err = mysqlmanger.UpdateOrDelete(delstr)
			fmt.Println(delstr)
			if err != nil {
				fmt.Println(err, "error")
				c.JSON(200, gin.H{"code": 400, "msg": "sql handle delete boke" + err.Error() + delstr})
				return
			}
			c.JSON(200, gin.H{"code": 200, "msg": "delete success"})
		})
		//增加更新学生
		en.POST("/addorupdatestu", func(c *gin.Context) {
			type Stu struct {
				ID     int     `db:"id" json:"id"`
				Name   string  `db:"name" json:"name"`
				Height float64 `db:"height" json:"height"`
				Age    int     `db:"age" json:"age,string"`
				Logo   string
			}
			content := c.PostForm("content")
			fmt.Println("=content", content)
			title := c.PostForm("title")
			if len(content) == 0 || len(title) == 0 {
				c.JSON(200, gin.H{"code": 400, "msg": "content-title为空"})
				return
			}
			id := c.PostForm("id")
			//更新过程
			if len(id) > 0 {
				idvalue, err := strconv.Atoi(id)
				if err != nil {
					c.JSON(200, gin.H{"code": "400", "msg": "id转化失败" + err.Error()})
					return
				}
				var total int
				sqlqueryStr := fmt.Sprintf("select count(*) as total from boke where id='%d'", idvalue)
				err = mysqlmanger.Get(sqlqueryStr, &total)
				if err != nil {
					c.JSON(200, gin.H{"code": 400, "msg": sqlqueryStr + err.Error()})
					return
				}
				updatestr := fmt.Sprintf("update boke set title='%s',content='%s' where id='%d'", title, content, idvalue)
				_, err = mysqlmanger.UpdateOrDelete(updatestr)
				if err != nil {
					c.JSON(200, gin.H{"code": 400, "msg": updatestr + err.Error()})
					return
				}
				c.JSON(200, gin.H{"code": 200, "msg": "更新成功"})
				return
			}

			sqlstr := fmt.Sprintf("insert into boke(title,content)values('%s','%s')", title, content)
			_, err := mysqlmanger.Insert(sqlstr)
			if err != nil {
				fmt.Println(err, "error")
				c.JSON(200, gin.H{"code": 400, "msg": "insert" + err.Error()})
				return
			}
			c.JSON(200, gin.H{"code": 200, "msg": "insert success"})

		})
		//测试
		en.Any("/test", func(c *gin.Context) {
			type Tes struct {
				ID   int    `db:"id" json:"id"`
				Name string `db:"name" json:"name"`
			}
			var tt []*Tes
			err := mysqlmanger.Select("select * from test", &tt)
			marshal, _ := json.Marshal(tt)
			fmt.Println(err, tt, string(marshal))

			//var t struct{
			//	Name string  `form:"name"`
			//	Age int `form:"age,string"`
			//}
			//支持form-data  ulecode-formdata
			//err := c.ShouldBind(&t)
			//c.PostForm()
			//fmt.Println(err,t)
			//支持application/JSON
			//err:=c.ShouldBindJSON(&t)
			//fmt.Println(err,t)

			//支持?name=liuhangkai&age=123 get
			//err := c.ShouldBindQuery(&t)
			//fmt.Println(err,t)
			//c.Query()
			//绑定uri binding做过滤校验的 gin内置验证器使用
			///test/:name/:age
			//var t struct{
			//	Name string  `uri:"name" binding:"required,email"`
			//	Age int `uri:"age,string"`
			//}
			//`form:"id,string" binding:"omitempty,lt=6000,gt=1"` //omitempty要么不传，传的话就要// [1,6000]
			//err:=c.ShouldBindUri(&t)
			////c.Param()
			//fmt.Println(err,t)
		})
		en.GET("/getinfo", func(c *gin.Context) {
			var bigResult = make(map[string]interface{})
			v, _ := mem.VirtualMemory()
			bigResult["memTotal"] = fmt.Sprintf("%d", v.Total)
			bigResult["memFree"] = fmt.Sprintf("%d", v.Free)
			bigResult["memUsed"] = fmt.Sprintf("%f%%", v.UsedPercent)
			percent, _ := cpu.Percent(time.Second, false)
			bigResult["cpuuse"] = fmt.Sprintf("%f%%", percent[0])
			hInfo, _ := host.Info()
			bigResult["hostname"] = hInfo.Hostname
			bigResult["platform"] = hInfo.Platform
			info, _ := net.IOCounters(true)
			for index, v := range info {
				if v.Name == "本地连接 2" || index == 0 {
					bigResult["netsend"] = fmt.Sprintf("%d", v.BytesSent)
					bigResult["netrecv"] = fmt.Sprintf("%d", v.BytesRecv)
					break
				}

			}

			loginip := strings.Split(c.Request.RemoteAddr, ":")[0]
			bigResult["clientip"] = loginip
			parts, _ := disk.Partitions(true)
			var temp []map[string]string
			for _, part := range parts {
				t := make(map[string]string)
				diskInfo, _ := disk.Usage(part.Mountpoint)

				t["name"] = part.Device
				t["usedper"] = fmt.Sprintf("%f%%", diskInfo.UsedPercent)
				t["total"] = fmt.Sprintf("%d", diskInfo.Total)
				t["free"] = fmt.Sprintf("%d", diskInfo.Free)
				temp = append(temp, t)
			}
			bigResult["disk"] = temp

			for k, v := range getlocation(loginip) {
				bigResult[k] = v
			}
			c.JSON(200, gin.H{"code": 200, "data": bigResult})

		})
		//go func() {
		//	for {
		//		fmt.Println("===reslutmap", WebSocketMap)
		//		time.Sleep(5 * time.Second)
		//	}
		//}()
		en.GET("/conn", func(c *gin.Context) {
			// senduserid|type(1close)|msg
			userid := c.Query("userid")
			if len(userid) == 0 {
				fmt.Println(userid, "weikong")
				return
			}
			fmt.Println(userid, "userid")
			lock.RLock()
			v, ok := WebSocketMap[userid]
			lock.RUnlock()
			if ok {
				lock.Lock()
				var temp WebSocketMsg
				temp.From = userid
				temp.To=userid
				temp.MsgType = SOCKET_MSG_ERROR
				temp.MsgError = "该通道即将被关闭,然后在重新打开"
				v.WriteMessage(websocket.TextMessage, getWebMsg(temp))
				time.Sleep(time.Millisecond * 10)
				v.Close()
				delete(WebSocketMap, userid)
				lock.Unlock()
				fmt.Println("====delete")
			}
			conn, _ := upgrader.Upgrade(c.Writer, c.Request, nil)
			lock.Lock()
			WebSocketMap[userid] = conn
			lock.Unlock()
			ch := make(chan string, 1)
			go readerMessage(ch, conn, userid)
			go writeMes(ch, conn, userid)
		})

		en.POST("/sendmsg", func(c *gin.Context) {
			  var msg struct {
				Userid string `form:"userid" binding:"required"`
				Content string `form:"content" binding:"required"`
				To string `form:"to" binding:"required"`
				MsType int `form:"msgtype,string" binding:"required"`
				Service string `form:"service" binding:"omitempty,gt=1"`
			}
			err := c.ShouldBind(&msg)
			if err!=nil{
				c.JSON(200,gin.H{"code":400,"msg":"err"+err.Error()})
				return
			}
			if msg.To == msg.Userid{
				c.JSON(200,gin.H{"code":400,"msg":"userid不能和to一样"})
				return
			}

			lock.RLock()
			v, ok := WebSocketMap[msg.To]
			lock.RUnlock()
			var temp WebSocketMsg
			temp.From = msg.Userid
			temp.To=msg.To
			if ok {
				if(msg.MsType == SOCKET_MSG){
					temp.Content=msg.Content
					temp.MsgType=msg.MsType
					v.SetWriteDeadline(time.Now().Add(writeWait))
					err := v.WriteMessage(websocket.TextMessage, getWebMsg(temp))
					if err!=nil{
						c.JSON(200,gin.H{"code":204,"msg":"写入超时"})
						return
					}
				}else if(msg.MsType == SOCKET_CLOSE){
					temp.Content=msg.Content
					temp.MsgType=msg.MsType
					v.SetWriteDeadline(time.Now().Add(writeWait))
					v.WriteMessage(websocket.TextMessage, getWebMsg(temp))
					time.Sleep(time.Nanosecond*10)
					v.Close()
				}else {
					c.JSON(200,gin.H{"code":204,"msg":"msgType错误"})
					return
				}
				c.JSON(200,gin.H{"code":200,"msg":"sendSuccess"})
				return
			}
			//没有找到对应userid
			c.JSON(200,gin.H{"code":201,"msg":"没有找到对应的userid"})
			return


		})

		//v1 end
	}
}

func checkIsChecked(result []Menu, parm []string) []Menu {
	var ttt []Menu
	if len(parm) == 0 {
		return result
	}

	for _, me := range result {
		var flag bool = false
		for _, v := range parm {

			atoi, _ := strconv.Atoi(v)
			if atoi == me.Id {
				me.Checked = true
				ttt = append(ttt, me)
				flag = true
				break

			}
		}

		if flag == false {
			ttt = append(ttt, me)
		}

	}

	return ttt
}

func ServeHTTP(w http.ResponseWriter, r *http.Request) {

	dir, file := path.Split(r.URL.Path)
	ext := path.Ext(file)
	id := file[:len(file)-len(ext)]
	fmt.Println("file : " + file)
	fmt.Println("ext : " + ext)
	fmt.Println("id : " + id)
	if ext == "" || id == "" {
		http.NotFound(w, r)
		return
	}
	fmt.Println("reload : " + r.FormValue("reload"))
	if r.FormValue("reload") != "" {
		captcha.Reload(id)
	}
	lang := strings.ToLower(r.FormValue("lang"))
	download := path.Base(dir) == "download"
	if Serve(w, r, id, ext, lang, download, captcha.StdWidth, captcha.StdHeight) == captcha.ErrNotFound {
		http.NotFound(w, r)
	}
}

func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool, width, height int) error {
	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	w.Header().Set("Pragma", "no-cache")
	w.Header().Set("Expires", "0")

	var content bytes.Buffer
	switch ext {
	case ".png":
		w.Header().Set("Content-Type", "image/png")
		captcha.WriteImage(&content, id, width, height)
	case ".wav":
		w.Header().Set("Content-Type", "audio/x-wav")
		captcha.WriteAudio(&content, id, lang)
	default:
		return captcha.ErrNotFound
	}

	if download {
		w.Header().Set("Content-Type", "application/octet-stream")
	}
	http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes()))
	return nil
}
